//
// Created by HP on 2025/12/1.
//

#include "AdminLog.h"
#include <iostream>

AdminLog::AdminLog() : Model("admin_logs") {
    setTableDefault("operatorId", "VARCHAR(50) NOT NULL");
    setTableDefault("operatorName", "VARCHAR(100) NOT NULL");
    setTableDefault("action", "VARCHAR(100) NOT NULL");
    setTableDefault("targetObject", "VARCHAR(255)");
    setTableDefault("details", "TEXT");
    setTableDefault("ipAddress", "VARCHAR(50)");
    setTableDefault("success", "VARCHAR(10) NOT NULL DEFAULT 'true'");
    setTableDefault("createdAt", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
}

void AdminLog::bind(const std::string& key, const std::string& value) {
    if (!TableCols.count(key)) {
        std::cerr << "Error: Invalid key for admin_log bind" << std::endl;
        return;
    }
    
    std::string selectSql = "SELECT * FROM " + TableName + " WHERE " + key + " = '" + Model::escapeSqlLiteral(value) + "';";
    std::vector<std::map<std::string, std::string>> result = DBConnector::getInstance()->query(selectSql);

    if (result.empty()) {
        std::cerr << "bind failed: SQL execution error or no result. SQL: " << selectSql << std::endl;
        return;
    }

    std::cout << "bind success. Table: " << TableName << std::endl;

    // 日志记录可能有多条，这里取第一条
    if (result.size() > 1) {
        std::cout << "Warning: Multiple admin_log records found with the same " << key << ", using the first one." << std::endl;
    }
    
    this->id = result[0]["id"];
    this->operatorId = result[0]["operatorId"];
    this->operatorName = result[0]["operatorName"];
    this->action = result[0]["action"];
    this->targetObject = result[0]["targetObject"];
    this->details = result[0]["details"];
    this->ipAddress = result[0]["ipAddress"];
    this->success = result[0]["success"];
    this->createdAt = result[0]["createdAt"];
    this->isBind = true;
}

bool AdminLog::save() {
    std::string insertSql = "INSERT INTO " + TableName + " (operatorId, operatorName, action, targetObject, details, ipAddress, success) VALUES ('" 
                          + Model::escapeSqlLiteral(operatorId) + "', '" 
                          + Model::escapeSqlLiteral(operatorName) + "', '" 
                          + Model::escapeSqlLiteral(action) + "', '" 
                          + Model::escapeSqlLiteral(targetObject) + "', '" 
                          + Model::escapeSqlLiteral(details) + "', '" 
                          + Model::escapeSqlLiteral(ipAddress) + "', '" 
                          + Model::escapeSqlLiteral(success) + "');";
    
    int executeCode = DBConnector::getInstance()->execute(insertSql);
    if (executeCode == -1) {
        std::cerr << "save admin_log failed: SQL execution error. SQL: " << insertSql << std::endl;
        std::cerr << "Database error: " << DBConnector::getInstance()->getError() << std::endl;
        return false;
    } else {
        std::cout << "save admin_log success. Table: " << TableName << std::endl;
        return true;
    }
}
